package com.zenithmind.coding.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.coding.mapper.SubmissionMapper;
import com.zenithmind.coding.pojo.dto.SubmissionDTO;
import com.zenithmind.coding.pojo.entity.Submission;
import com.zenithmind.coding.pojo.vo.SubmissionVO;
import com.zenithmind.coding.service.SubmissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 代码提交服务实现类
 *
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SubmissionServiceImpl extends ServiceImpl<SubmissionMapper, Submission> implements SubmissionService {

    private SubmissionVO convertToVO(Submission submission) {
        if (submission == null) {
            return null;
        }
        SubmissionVO vo = new SubmissionVO();
        BeanUtils.copyProperties(submission, vo);
        return vo;
    }

    private List<SubmissionVO> convertToVOList(List<Submission> submissionList) {
        if (CollectionUtils.isEmpty(submissionList)) {
            return Collections.emptyList();
        }
        return submissionList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public SubmissionVO submitCode(SubmissionDTO submissionDTO) {
        log.info("提交代码: {}", submissionDTO);
        Submission submission = new Submission();
        BeanUtils.copyProperties(submissionDTO, submission);
        submission.setStatus(0); // PENDING
        this.save(submission);
        // TODO: 在这里触发异步判题流程
        return convertToVO(submission);
    }

    @Override
    public PageResult<SubmissionVO> getSubmissionPage(Long current, Long size, String userId,
                                                      String problemId, String language, Integer status,
                                                      LocalDateTime startTime, LocalDateTime endTime) {
        log.info("分页查询提交记录: current={}, size={}, userId={}, problemId={}, language={}, status={}, startTime={}, endTime={}",
                current, size, userId, problemId, language, status, startTime, endTime);

        Page<Submission> page = new Page<>(current, size);
        IPage<Submission> pageResult = baseMapper.selectSubmissionPage(page, userId, problemId, language, status, startTime, endTime);

        List<SubmissionVO> voList = convertToVOList(pageResult.getRecords());
        return PageResult.of(voList, pageResult.getTotal());
    }

    @Override
    public SubmissionVO getSubmissionById(String id) {
        log.info("根据ID查询提交详情: id={}", id);
        Submission submission = this.getById(id);
        return convertToVO(submission);
    }

    @Override
    public Boolean rejudgeSubmission(String id) {
        log.info("重新评判: id={}", id);
        Submission submission = new Submission();
        submission.setId(id);
        submission.setStatus(0); // PENDING
        submission.setStatusMessage("Rejudging");
        submission.setRunTime(null);
        submission.setRunMemory(null);
        submission.setScore(null);
        
        boolean success = this.updateById(submission);
        if (success) {
            // TODO: 发送到消息队列进行判题
        }
        return success;
    }

    @Override
    public SubmissionVO getUserBestSubmission(String userId, String problemId) {
        log.info("获取用户最佳提交: userId={}, problemId={}", userId, problemId);
        Submission submission = baseMapper.selectUserBestSubmission(userId, problemId);
        return convertToVO(submission);
    }

    @Override
    public List<SubmissionVO> getProblemBestSubmissions(String problemId, Integer limit) {
        log.info("获取问题最佳提交: problemId={}, limit={}", problemId, limit);
        List<Submission> submissions = baseMapper.selectProblemBestSubmissions(problemId, limit);
        return convertToVOList(submissions);
    }

    @Override
    public List<SubmissionVO> getRecentSubmissions(String userId, Integer limit) {
        log.info("获取最近提交: userId={}, limit={}", userId, limit);
        List<Submission> submissions = baseMapper.selectRecentSubmissions(userId, limit);
        return convertToVOList(submissions);
    }

    @Override
    public List<SubmissionVO> getExcellentSubmissions(String problemId, String language, Integer limit) {
        log.info("获取优秀提交: problemId={}, language={}, limit={}", problemId, language, limit);
        List<Submission> submissions = baseMapper.selectPublicExcellentSubmissions(problemId, language, limit);
        return convertToVOList(submissions);
    }

    @Override
    public Boolean shareSubmission(String id) {
        log.info("分享提交: id={}", id);
        Submission submission = new Submission();
        submission.setId(id);
        submission.setIsShared(1);
        return this.updateById(submission);
    }

    @Override
    public Boolean unshareSubmission(String id) {
        log.info("取消分享提交: id={}", id);
        Submission submission = new Submission();
        submission.setId(id);
        submission.setIsShared(0);
        return this.updateById(submission);
    }

    @Override
    public Object getUserSubmissionStatistics(String userId, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("获取用户提交统计: userId={}, startTime={}, endTime={}", userId, startTime, endTime);
        return baseMapper.selectUserSubmissionStatistics(userId, startTime, endTime);
    }

    @Override
    public List<Object> getLanguageStatistics(LocalDateTime startTime, LocalDateTime endTime) {
        log.info("获取语言统计: startTime={}, endTime={}", startTime, endTime);
        List<SubmissionMapper.LanguageStatistics> stats = baseMapper.selectLanguageStatistics(startTime, endTime);
        return new ArrayList<>(stats);
    }

    @Override
    public List<Object> getSubmissionTrend(Integer days) {
        log.info("获取提交趋势: days={}", days);
        List<SubmissionMapper.SubmissionTrend> trend = baseMapper.selectSubmissionTrend(days);
        return new ArrayList<>(trend);
    }

    @Override
    public Object checkPlagiarism(String id) {
        log.info("检测代码抄袭: id={}", id);
        // 这是一个复杂的功能，具体实现依赖于查重策略
        log.warn("提交 {} 的代码查重功能尚未完全实现。", id);
        return null;
    }

    @Override
    public List<SubmissionVO> getSimilarSubmissions(String id, Double threshold, Integer limit) {
        log.warn("获取相似提交通能暂未实现，因为Submission实体缺少codeHash字段。");
        return Collections.emptyList();
    }

    @Override
    public String exportSubmissions(String userId, String problemId, String language, Integer status,
                                  LocalDateTime startTime, LocalDateTime endTime) {
        log.info("导出提交记录: userId={}, problemId={}, language={}, status={}, startTime={}, endTime={}",
                userId, problemId, language, status, startTime, endTime);

        // TODO: 实现Excel导出功能
        // 1. 查询符合条件的提交记录
        // 2. 生成Excel文件
        // 3. 上传到文件服务器或本地存储
        // 4. 返回下载链接

        log.warn("导出提交记录功能暂未完全实现");
        return "/downloads/submissions_export_" + System.currentTimeMillis() + ".xlsx";
    }
}